import { SettingOption } from './option'

interface MouseEventExtend extends MouseEvent {
  target: HTMLElement
}

// <ob-setting-select>
const SelectTemplate = document.createElement('template')
SelectTemplate.innerHTML = `<style>
    .hidden { display: none !important; }
</style>
<div part="parent">
        <div part="button">
            <input type="text" placeholder="请选择" part="current-text" />
            <svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" part="button-arrow">
                <path d="M12 6.0001L8.00004 10L4 6" stroke="currentColor" stroke-linejoin="round"></path>
            </svg>
        </div>
    <ul class="hidden" part="option-list"><slot></slot></ul>
</div>`

window.customElements.define(
  'ob-setting-select',
  class extends HTMLElement {
    readonly _button: HTMLDivElement
    readonly _text: HTMLInputElement
    readonly _context: HTMLUListElement

    constructor() {
      super()

      this.attachShadow({ mode: 'open' })
      this.shadowRoot?.append(SelectTemplate.content.cloneNode(true))

      this._button = this.shadowRoot?.querySelector('div[part="button"]')!
      this._text = this.shadowRoot?.querySelector('input[part="current-text"]')!
      this._context = this.shadowRoot?.querySelector('ul[part="option-list"]')!

      const buttonClick = () => {
        const isHidden = this._context.classList.toggle('hidden')
        window[`${isHidden ? 'remove' : 'add'}EventListener`]('pointerdown', windowPointerDown)
      }

      const windowPointerDown = ({ target }) => {
        if (!this.contains(target)) buttonClick()
      }

      this._button.addEventListener('click', buttonClick)
      this._context.addEventListener('click', e => {
        const { target } = e as MouseEventExtend
        if (target.tagName !== 'SETTING-OPTION') return
        buttonClick()

        if (target.hasAttribute('is-selected')) return

        this.querySelectorAll('setting-option[is-selected]').forEach((dom) => dom.toggleAttribute('is-selected'))
        target.toggleAttribute('is-selected')

        this._text.value = target.textContent!
        this.dispatchEvent(
          new CustomEvent('selected', {
            bubbles: true,
            composed: true,
            detail: {
              name: target.textContent,
              value: target.dataset.value,
            },
          }),
        )
      })

      this._text.value = this.querySelector('setting-option[is-selected]')?.textContent!
    }
  },
)

export const SettingSelect = (items: Array<{ text: string; value: string }>, configKey?: string, configValue?: any) => {
  return `<ob-setting-select ${configKey ? `data-config-key="${configKey}"` : ''}>
    ${items
      .map((e, i) => {
        return SettingOption(e.text, e.value, configKey && configValue ? configValue === e.value : i === 0)
      })
      .join('')}
</ob-setting-select>`
}
